#include "ImageFragment.h"
#include "../Scene/ZDataManager.h"
#include "../Tools/ConfigManager.h"

GLOBAL_NAMESPACE_BEGIN
NAMESPACE_MACHINE_LEARNING_BEGIN


void ImageFragmentParams::output(std::ostream& out)
{
    out << u << " " << v << " " << w << " " << h;
}

void ImageFragmentParams::input(std::istream& in)
{
    in >> u >> v >> w >> h;
}

void ImageFragmentParams::setPath(const char* filePath)
{
    fragmentPath = std::string(filePath);
}

///////////////////////////////////////////////////////////////
//

ImageFragment::ImageFragment(const char* imaPath)
    : ima_(NULL)
    , templateImg_(NULL)
    , maskImg_(NULL)
    , bValid_(false)
{

}

ImageFragment::ImageFragment(const ImageFragmentParamsIO& io)
    : ima_(NULL)
    , templateImg_(NULL)
    , maskImg_(NULL)
    , bValid_(false)
    , bUseIoInitialize_(true)
{
    init(io);
}

ImageFragment::ImageFragment(ImageSpace::Image* ima, const ImageFragmentParams& para)
    : ima_(ima)
    , templateImg_(NULL)
    , maskImg_(NULL)
    , bValid_(false)
    , bUseIoInitialize_(false)
    , order_(-1)
{
    init(para);
}

bool ImageFragment::isValid()
{
    return bValid_;
}

void ImageFragment::init(const ImageFragmentParams& para)
{
    if (!ima_) return;
    params_ = para;
    //cv::Rect roi(para.u, para.v, para.u+para.w, para.v+para.h);
    //ima_->getData()->operator()(roi).copyTo(*templateImg_->getData());
    //fragmentPath_ = std::string(para.fragmentPath);
    //bValid_ = true;
}

void ImageFragment::init(const ImageFragmentParamsIO& io)
{
    // read images
    ima_         = DataManager::getSingletonPtr()->readImage(io.imaFullPath.c_str(), io.id);
    templateImg_ = DataManager::getSingletonPtr()->readImage(io.templateFullPath.c_str(), io.templateId);
    maskImg_     = DataManager::getSingletonPtr()->readImage(io.maskFullPath.c_str(), io.maskId);
    order_       = io.order;
    //init(io.fragmentPara);
    params_ = io.fragmentPara;
    bUseIoInitialize_ = true;
}

ImageSpace::Image* ImageFragment::finalize()
{
    if (bValid_) return templateImg_;

    if (bUseIoInitialize_)
    {

    }
    else
    {
        // template image
        if (templateImg_)
        {
            DataManager::getSingletonPtr()->removeImage(templateImg_);
            templateImg_ = NULL;
        }
        templateImg_ = new ImageSpace::Image(ImageSpace::Image::IMAGE_Template, ima_, params_.fragmentPath);
        //generateTemplateImageNames(ima_, templateImg_);
        DataManager::getSingletonPtr()->addImage(templateImg_);
        cv::Rect roi(params_.u, params_.v, params_.w, params_.h);
        ima_->getData()->operator()(roi).copyTo(*templateImg_->getData());

        // mask image
        if (maskImg_)
        {
            DataManager::getSingletonPtr()->removeImage(maskImg_);
            maskImg_ = NULL;
        }
        maskImg_ = new ImageSpace::Image(ImageSpace::Image::IMAGE_Mask, ima_, params_.fragmentPath);
        //generateMaskImaegNames(ima_, maskImg_);
        DataManager::getSingletonPtr()->addImage(maskImg_);
        (*maskImg_->getData()) = cv::Mat(ima_->getData()->size(), CV_8UC1, cv::Scalar(0));
        cv::Rect roiMask(int(params_.w/2)+params_.u-3, int(params_.h/2)+params_.v-3, 7, 7);
        maskImg_->getData()->operator()(roiMask).setTo(255);

        bValid_ = true;
    }

    //cv::imwrite(ima_->getName(), *ima_->getData());
    //cv::imwrite("template.jpg", *templateImg_->getData());
    //cv::imwrite("mask.jpg", *maskImg_->getData());

    return templateImg_;
}

const ImageSpace::Image* ImageFragment::getTemplateImage() const
{
    return templateImg_;
}

const ImageSpace::Image* ImageFragment::getMaskImage() const
{
    return maskImg_;
}

const ImageFragmentParams* ImageFragment::getFragmentParams() const
{
    return &params_;
}

const ImageSpace::Image* ImageFragment::getImage() const
{
    return ima_;
}

void ImageFragment::setOrder(int order)
{
    order_ = order;
}

int ImageFragment::getOrder() const
{
    return order_;
}

void ImageFragment::output(std::ostream& out)
{
    out << ima_->getName() << "\n";
    params_.output(out);
}

NAMESPACE_MACHINE_LEARNING_END
GLOBAL_NAMESPACE_END

